// event funcs  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


chess_spider.events = {

// from movelist move.href: jump to this position on current board
'moveJump': function( e ) {
	e.stopPropagation();
	e.preventDefault();
	if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;

	var move = chess_spider.state.moves[this.getAttribute('move_id')];
	var game = move.game;
	var board = game.cur_bd;
	if( board ) board.userJump( move );
},

// state space for drag
'dragstate': {
	'srcImg':	null,		// clicked on image (or div) that begins drag
	'board':	null,		// board on which drag and drop is occurring
	'srcCell':	null,		// td holding image
	'curCell':	null,		// td where dragEnter has entered
	'tgtCell':	null,		// curCell if valid target for drop
	'move':		null,		// move that will occur if dropped (in not, move needs to be deleted)
	'setup':	null		// whether in setup mode
},

// piece (image or div) drag  - - - - - - - - - - - - - - - - - - - -
'dragstart': function( e ) {
	
	if( e.target.parentNode.ancestorByAttribute('cs__disabled','true',true) ) return;

	console.log( 'begin dragstart '+e.type+' - '+e.target+' - '+e.target.draggable );

	// nullify
	//-e.stopPropagation();
	//-e.preventDefault();
	//-return;
	
	// need to see if in setup mode
	chess_spider.events.dragstate.setup = ( this.cs__getFixedBoard() && this.cs__getFixedBoard().mode == 'setup' );
	
	// cannot drag if state not ready
	if( !chess_spider.events.dragstate.setup && !chess_spider.state.ready ) {
		console.log( 'dragstart: not ready' );
		return;
	}

	// set up drag
	e.dataTransfer.effectAllowed='move';
	e.dataTransfer.dropEffect='move';
	e.dataTransfer.setDragImage(this,0,0);

	// state
	chess_spider.events.dragstate.srcImg  = this;
	chess_spider.events.dragstate.srcCell = chess_spider.events.dragstate.srcImg.parentNode;	// td holding image
	chess_spider.events.dragstate.curCell = null;
	chess_spider.events.dragstate.tgtCell = null;
	chess_spider.events.dragstate.move    = null;
	chess_spider.events.dragstate.board   = chess_spider.events.dragstate.srcCell.cs__getBoard();
	console.log( 'srcCell='+chess_spider.events.dragstate.srcCell.tagName+', board='+chess_spider.events.dragstate.board );

	// make sure set cur board
	if( chess_spider.state.cur_bd != chess_spider.events.dragstate.board ) chess_spider.events.dragstate.board.setCur();
},

// enter square - called in closure
// closure for dragLeave, drop
'dragenter': function( e ) {

	// if not dragging or if this is original square or if we are already here: nada
	if( !chess_spider.events.dragstate.srcCell || !chess_spider.events.dragstate.board
	 || this == chess_spider.events.dragstate.srcCell || this == chess_spider.events.dragstate.curCell ) return;

	// here we are
	console.log( 'dragenter:  this='+this.getAttribute('sq')+' - e.target='+e.target.tagName );

	// nullify
	//-e.stopPropagation();
	//-e.preventDefault();
	//-return;
	
	chess_spider.events.dragstate.curCell = this;
	//-console.log( 'set chess_spider.events.dragstate.curCell = '+chess_spider.events.dragstate.curCell.getAttribute('sq') );

	// if already a move, get rid of it
	if( chess_spider.events.dragstate.move ) chess_spider.events.dragstate.move.delete();
	chess_spider.events.dragstate.move = null;
	chess_spider.events.dragstate.tgtCell = null;

	// grab move - if false, move was illegal
	//-console.log( 'assign move from '+chess_spider.events.dragstate.srcCell.getAttribute('sq')+' to '+chess_spider.events.dragstate.curCell.getAttribute('sq') );
	if( !chess_spider.events.dragstate.setup ) try {
		//-console.log( 'genMove( '+board.cur_mv.id+', '+chess_spider.events.dragstate.srcCell.getAttribute('sq')+', '+chess_spider.events.dragstate.curCell.getAttribute('sq')+' )' );
		chess_spider.events.dragstate.move = chess_spider.events.dragstate.board.cur_mv.genMove(
			chess_spider.events.dragstate.board,
			chess_spider.events.dragstate.srcCell.getAttribute('sq'),
			chess_spider.events.dragstate.curCell.getAttribute('sq') );
	}
	// log incorrect moves
	catch( msg ) {
		console.log( 'illegal move: ' + msg );
	}

	// move ok
	if( chess_spider.events.dragstate.move || chess_spider.events.dragstate.setup ) {

		console.log( 'valid target '+chess_spider.events.dragstate.curCell.getAttribute('sq') );

		// valid target cell
		chess_spider.events.dragstate.tgtCell = chess_spider.events.dragstate.curCell;

		// highlight cell
		chess_spider.events.border( chess_spider.events.dragstate.tgtCell, true );
	}
},

// over
'dragover': function( e ) {
	//-e.stopPropagation();
	e.preventDefault();		// this is necessary for drop to actually take place
},

// leave the square - called in closure
'dragleave': function( e ) {

	//-e.stopPropagation();
	//-console.log( 'drag leave: this='+this.getAttribute('sq') );

	// costumes
	//=chess_spider.events.dragstate.curCell.classList.remove('cs__move');
	chess_spider.events.border( this, false );
	//-console.log('drag leave removing border from '+this.getAttribute('sq'));
},

// utility
'border': function( cell, draw ) {

	// redraw border on cell
	cell.style.border = (draw) ? '1px solid red' : '1px solid gray';

	// if setup, restore heavy borders top and bottom rows of setup
	var board = cell.cs__getBoard();
	if( board.mode == 'setup' ) {
		for( var i=0; i<board.dom_table().rows[0].cells.length; i++ )
			board.dom_table().rows[0].cells[i].style.borderBottom = '3px solid black';
		for( var i=0; i<board.dom_table().rows[9].cells.length; i++ )
			board.dom_table().rows[9].cells[i].style.borderTop = '4px solid black';
	}
},

// drop the piece into the square - called in closure
'drop': function( e ) {

	//-e.stopPropagation();
	console.log( 'drop: this='+this.getAttribute('sq') );

	// this != target: fatal error - ??
	// todo: this is now console.log instead of throw until proven error
	// might occur when moving piece back to its origin, for example
	if( chess_spider.events.dragstate.move && this != chess_spider.events.dragstate.tgtCell ) {
		console.log( "ERROR?! this="+this.getAttribute('sq')
			+" chess_spider.events.dragstate.tgtCell="+chess_spider.events.dragstate.tgtCell.getAttribute('sq') );
	}

	// costumes
	//=chess_spider.events.dragstate.curCell.classList.remove('cs__move');
	this.style.border = '1px solid gray';
	this.style.backgroundColor = '';
	//-console.log('drop removing border from '+chess_spider.events.dragstate.curCell.getAttribute('sq'));

	// if move, attach move and eat carried piece
	if( chess_spider.events.dragstate.move ) chess_spider.events.dragstate.move.attach( chess_spider.events.dragstate.board );

	// if setup, create piece on board, and reject the dropped piece
	else if( chess_spider.events.dragstate.setup ) {

		//-console.log( 'setup move from '+chess_spider.events.dragstate.srcCell.getAttribute('sq') );

		// create piece on board same the piece we were moving (include space)
		chess_spider.events.dragstate.board.set( chess_spider.events.dragstate.tgtCell.getAttribute('sq'),
				chess_spider.events.dragstate.srcImg.getAttribute('name').substr(4,1),
				chess_spider.events.dragstate.srcImg.getAttribute('name').substr(5,1), true );

		// if piece coming from onboard, make blank
		if( chess_spider.events.dragstate.srcCell.getAttribute('sq').substr(1,1) > '0'
		&&  chess_spider.events.dragstate.srcCell.getAttribute('sq').substr(1,1) < '9' ) {
			chess_spider.events.dragstate.board.set( chess_spider.events.dragstate.srcCell.getAttribute('sq'), 'w', ' ', true );
		}
	}

	// null params
	chess_spider.events.dragend(e);
},

// end of drag
'dragend': function( e ) {

	//-e.stopPropagation();

	console.log( 'begin end (target)'+e.target.tagName+'/(this)'+this.tagName );

	// null params
	chess_spider.events.dragstate.srcImg  = null;
	chess_spider.events.dragstate.srcCell = null;
	chess_spider.events.dragstate.curCell = null;
	chess_spider.events.dragstate.tgtCell = null;
	chess_spider.events.dragstate.move    = null;
	chess_spider.events.dragstate.board   = null;
},


// backrank square.click - pawnpromotion
'cyclePromotion': function( e ) {

	if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;

	// environment
	var board = e.target.cs__getBoard();
	var sq = e.target.getAttribute('sq');
	var piece = (e.target.firstChild) ? e.target.firstChild.name[1] : ' ';
	var lastMove = board.cur_mv;

	// if current (last) move is this square - add promotion!
	if( !lastMove.promotion || lastMove.tgt_sq != sq ) return;

	// cycle promotion
	if( lastMove.promotion == 'q' )		lastMove.promotion = 'n';
	else if( lastMove.promotion == 'n' )	lastMove.promotion = 'b';
	else if( lastMove.promotion == 'b' )	lastMove.promotion = 'r';
	else if( lastMove.promotion == 'r' )	lastMove.promotion = 'q';

	//-alert( 'sq='+sq+', tgt_sq='+lastMove.tgt_sq+', new.promotion='+lastMove.promotion );
	
	// re-apply a move
	lastMove.reApply();

	// have board refresh
	board.userJump( board.cur_id );
},

// board.onclick - make this the active board
'boardTouch': function( e ) {

	// no ripple
	e.stopPropagation();
	e.preventDefault();
	//-console.log( 'boardTouch: disabled_node='+e.target.ancestorByAttribute('cs__disabled','true',true) );
	if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;

	// get board from table that triggered this event
	var board = e.target.cs__getBoard();

	// if move set cur
	board.setCur();
},

// keypress - hook to board and movelist
'keyDown': function( e ) {

	if( !e ) e = window.event;
	if( !chess_spider.params.control.keystrokes ) return;
	if( e.target.ancestorByAttribute('cs__disabled','true',true) ) return;

	// keystrokes not enabled
	if( !chess_spider.params.control.keystrokes ) return;

	//-alert( 'keyCode=' + e.keyCode + ', target=' + e.target.tagName );
	//-return;
	
	// current board - make sure set
	var bd = chess_spider.state.cur_bd;
	if( !bd ) return;

	// if input or textarea, let it go
	if( e.target.tagName == 'INPUT' || e.target.tagName == 'TEXTAREA' ) return;

	// left - previous move
	if( e.keyCode == 37 ) bd.userJump( -1 );

	// right - next move
	else if( e.keyCode == 39 ) bd.userJump( 1 );

	// tab - next board
	else if( e.keyCode == 9 && !e.shiftKey ) {

		// all boards available
		var boards = chess_spider.Board.boards();

		// look from where we are
		for( var i=boards.indexOf(chess_spider.state.cur_bd)+1; i<boards.length; i++ ) {
			//-console.log( i + ': ' + boards[i].root_mv.game.idx + ', ' + chess_spider.state.cur_bd.root_mv.game.idx );
			if( !boards[i].root_mv ) continue;
			if( boards[i].root_mv.game == chess_spider.state.cur_bd.root_mv.game ) break;
		}

		// if not found, look from beginning
		if( i > boards.length ) for( i=0; i<=boards.indexOf(chess_spider.state.cur_bd); i++ ) {
			if( !boards[i].root_mv ) continue;
			if( boards[i].root_mv.game == chess_spider.state.cur_bd.root_mv.game ) break;
		}

		// found new current board for this game
		chess_spider.state.cur_bd.root_mv.game.setCur( boards[i] );
	}
	// shift-tab - prev board
	else if( e.keyCode == 9 && e.shiftKey ) {

		// all boards available
		var boards = chess_spider.Board.boards();

		// look from where we are
		for( var i=boards.indexOf(chess_spider.state.cur_bd)-1; i>=0; i-- ) {
			//-console.log( i + ': ' + boards[i].root_mv.game.idx + ', ' + chess_spider.state.cur_bd.root_mv.game.idx );
			if( !boards[i].root_mv ) continue;
			if( boards[i].root_mv.game == chess_spider.state.cur_bd.root_mv.game ) break;
		}

		// if not found, look from beginning
		if( i < 0 ) for( i=boards.length-1; i>=0; i-- ) {
			if( !boards[i].root_mv ) continue;
			if( boards[i].root_mv.game == chess_spider.state.cur_bd.root_mv.game ) break;
		}

		// found new current board for this game
		chess_spider.state.cur_bd.root_mv.game.setCur( boards[i] );
	}
	// home - root mv
	else if( e.keyCode == 36 ) bd.userJump('start');
	
	// end - last move in branch
	else if( e.keyCode == 35 ) bd.userJump('....');

	// pageup - prev game
	else if( e.keyCode == 33 ) {
		//-console.log( 'from '+chess_spider.state.cur_bd.root_mv.game.idx );
		var i = (  chess_spider.state.cur_bd.root_mv.game.idx-1 < 0 ) ? chess_spider.state.game_arr.length-1 : chess_spider.state.cur_bd.root_mv.game.idx-1;
		//-console.log( 'pageUp to '+i );
		chess_spider.Game.display( i, chess_spider.params.movelist_dflt, chess_spider.params.fixedboard_dflt );
	}
	// pagedown - next game
	else if( e.keyCode == 34 ) {
		//-console.log( 'from '+chess_spider.state.cur_bd.root_mv.game.idx );
		var i = (  chess_spider.state.cur_bd.root_mv.game.idx+1 >= chess_spider.state.game_arr.length ) ? 0 : chess_spider.state.cur_bd.root_mv.game.idx+1;
		//-console.log( 'pageDn to '+i );
		chess_spider.Game.display( i, chess_spider.params.movelist_dflt, chess_spider.params.fixedboard_dflt );
	}
	// delete or ctl-z - delete move
	else if( e.keyCode == 46 && !e.shiftKey || e.keyCode == 90 && e.ctrlKey ) {
		var move = chess_spider.state.cur_bd.cur_mv;
		if( move.mode == 'user' ) move.userDelete( false );
	}
	// shift-delete - delete branch
	else if( e.keyCode == 46 && e.shiftKey ) {
		var move = chess_spider.state.cur_bd.cur_mv;
		if( move.mode == 'user' ) move.userDelete( true );
	}
	// insert - toggle screen
	else if( e.keyCode == 45 ) {
		chess_spider.state.cur_bd.dom_div.displayToggle();
	}
	// nada - let keystroke go through
	else	return;

	e.stopPropagation();
	e.preventDefault();
}

}
